package com.gun3y.controller;

import java.util.Collection;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.gun3y.SWService;
import com.gun3y.entity.Wrapper;
import com.gun3y.entity.result.ResultField;
import com.gun3y.entity.visual.TreeNode;
import com.gun3y.exception.ExceptionCode;
import com.gun3y.exception.SWException;
import com.gun3y.manager.MovieGraphManager;
import com.gun3y.manager.WrapperGraphManager;
import com.gun3y.utils.Commons;

@Controller
@RequestMapping("/ajax/")
public class AjaxController {

    @Autowired
    private MovieGraphManager movieGraphManager;

    @Autowired
    private WrapperGraphManager wrapperGraphManager;

    @Autowired
    private SWService service;

    @RequestMapping(value = "/wrapper-detail/{id}", method = RequestMethod.GET)
    @ResponseBody
    public Wrapper getWrapper(@PathVariable String id) {
	if (StringUtils.isBlank(id))
	    throw new SWException(ExceptionCode.InvalidInput);

	return wrapperGraphManager.getWrapperByName(id);
    }

    @RequestMapping(value = "/wrapper-test", method = RequestMethod.POST, consumes = "application/json")
    @ResponseBody
    public List<ResultField> testWrapper(@RequestBody Wrapper wrapper, @RequestParam("test") String testUrl) {

	if (StringUtils.isBlank(testUrl) || wrapper == null || !wrapper.validate())
	    throw new SWException(ExceptionCode.InvalidInput);

	return service.retrieve(wrapper, testUrl);
    }

    @RequestMapping(value = "/wrapper-save", method = RequestMethod.POST, consumes = "application/json")
    @ResponseBody
    public void saveWrapper(@RequestBody Wrapper wrapper) {
	if (wrapper == null)
	    throw new SWException(ExceptionCode.InvalidInput);

	wrapperGraphManager.updateWrapper(wrapper);
    }

    @RequestMapping(value = "/wrapper-all", method = RequestMethod.GET)
    @ResponseBody
    public Collection<Wrapper> getAllWrappers() {
	return wrapperGraphManager.getAllWrappers();
    }

    @RequestMapping(value = "/wrapper-enrich", method = RequestMethod.GET)
    @ResponseBody
    public void enrich(@RequestParam("wrapper") String wrapperName, @RequestParam("url") String url) {
	if (StringUtils.isBlank(url) || StringUtils.isBlank(wrapperName) || !wrapperGraphManager.exists(wrapperName))
	    throw new SWException(ExceptionCode.InvalidInput);

	Wrapper wrapper = wrapperGraphManager.getWrapperByName(wrapperName);
	List<ResultField> resultFields = service.retrieve(wrapper, url);

	movieGraphManager.updateMovie(url, resultFields);
    }

    @RequestMapping(value = "/show", method = RequestMethod.POST, produces = "application/json")
    @ResponseBody
    public String handleShowResponse(@RequestParam("data") String json, HttpServletRequest request, HttpServletResponse response) {
	response.setContentType("application/json");
	return Commons.decode(json);
    }

    @RequestMapping(value = "/tree-view/{type}", method = RequestMethod.GET, produces = "application/json")
    @ResponseBody
    public String handleTreeNode(@PathVariable("type") String type, HttpServletResponse response) {
	response.setContentType("application/json");
	if ("movie".equalsIgnoreCase(type)) {
	    return TreeNode.createMovieTree(movieGraphManager.getMovies()).toString();
	}
	else {
	    return TreeNode.createWrapperTree(wrapperGraphManager.getAllWrappers()).toString();
	}
    }

    @RequestMapping(value = "/clean-movie-db", method = RequestMethod.GET)
    @ResponseBody
    public void cleanMovieDB() {
	movieGraphManager.clear();
    }

    @RequestMapping(value = "/clean-wrapper-db", method = RequestMethod.GET)
    @ResponseBody
    public void cleanWrapperDB() {
	wrapperGraphManager.clear();
    }

    @ExceptionHandler(SWException.class)
    @ResponseBody
    public String handleIOException(SWException e) {
	return e.getCode().toString();
    }

    @ExceptionHandler(Exception.class)
    @ResponseBody
    public String handleIOException(Exception e) {
	return e.getMessage();
    }
}
